#include <user.h>

static int fio(int argc, ...) __attribute__ ((noinline));

static int 
fio(int argc, ...)
{
	 va_list   va;
	 int       i;	 
	 uint32_t  c = upriv->io_count;
	 uint32_t *buf = upriv->io_buf;

	 if (c + argc + 1 > upriv->io_buf_cap)
	 {
		  /* TODO: full error */
		  return -1;
	 }
	 
     va_start(va, argc);
	 
	 buf[c ++] = (uint32_t)upriv->fiber_cur;
	 for (i = 0; i != argc; ++ i)
	 {
		  uint32_t v;
		  buf[c ++] = va_arg(va, uint32_t);
	 }
	 
	 va_end(va);
	 upriv->io_count = c;

	 fiber_yield_io();
	 return 0;
}

void
fio_kprintf(const char *fmt, ...)
{
	 va_list va;
     va_start(va, fmt);
     fio(3, SC_KPRINTF, (uint32_t)fmt, (uint32_t)va);
     va_end(va);
}

void
fio_dummy_work(uint32_t workset_pages)
{
	 fio(2, SC_DUMMY_WORK, workset_pages);
}

void
fio_uevent_touch(void)
{
	 fio(1, SC_UEVENT_TOUCH);
}

void
fio_notify(fiber_t f)
{
	 fio(2, SC_UEVENT_ACTIVATE, (uint32_t)f);
}
